package cn.highedu.coolshark_product.security;

import cn.highedu.coolshark_product.pojo.vo.AdminLoginInfoVO;
import cn.highedu.coolshark_product.service.ex.ServiceCode;
import cn.highedu.coolshark_product.service.ex.ServiceException;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;

/**
 * 生产和解析token
 */
@Component
@Slf4j
public class JwtTokenHandler {
    // 密钥
    private String SECRET_KEY = "coolshark_product_key12345678901";
    // 过期时间 1小时
    private long Duration_Minute = 60 * 60 * 1000;

    public JwtTokenHandler() {
        log.debug("JwtTokenHandler对象创建");
    }

    /**
     * 把UserDetailsImpl对象转换为JWT字符串
     * @param userDetails
     * @return
     */
    public String createToken(UserDetailsImpl userDetails) {
        AdminLoginInfoVO adminLoginInfoVO = userDetails.getAdmin();
        return createToken(adminLoginInfoVO);
    }

    /**
     * 把JWT字符串解析为UserDetailsImpl对象
     * @param jwt
     * @return
     */
    public UserDetailsImpl parseJwtToken(String jwt) {
        AdminLoginInfoVO adminLoginInfoVO = parseToken(jwt);
        return new UserDetailsImpl(adminLoginInfoVO);
    }

    // 把AdminLoginInfoVO对象转换为JWT字符串
    private String createToken(AdminLoginInfoVO adminLoginInfoVO) {
        log.debug("开始创建JWT, 参数: {}", adminLoginInfoVO);
        // 从adminLoginInfo对象中获取数据
        String subject = adminLoginInfoVO.getUsername();
        Date now = new Date();
        Date exp = new Date(now.getTime() + Duration_Minute);
        Long id = adminLoginInfoVO.getId();
        Integer enable = adminLoginInfoVO.getEnable();
        String roles = String.join(",", adminLoginInfoVO.getRoles());
        String permissions = String.join(",", adminLoginInfoVO.getPermissions());
        // 创建JWT字符串
        String jwt = Jwts.builder()
                .setSubject(subject)
                .setIssuedAt(now)
                .setExpiration(exp)
                .claim("id", id)
                .claim("enable", enable)
                .claim("roles", roles)
                .claim("permissions", permissions)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
        log.debug("创建JWT成功, 结果: {}", jwt);
        return jwt;
    }
    // 将JWT字符串解析为AdminLoginInfoVO对象
    private AdminLoginInfoVO parseToken(String jwt) {
        log.debug("开始解析JWT, 参数: {}", jwt);
        try {
            // 解析JWT字符串
            Claims claims = Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(jwt)
                    .getBody();
            // 从JWT中获取数据
            Long id = Long.parseLong(claims.get("id").toString());
            String username = claims.get("sub").toString();
            Integer enable = Integer.parseInt(claims.get("enable").toString());
            String roles = claims.get("roles").toString();
            String permissions = claims.get("permissions").toString();
            // 创建AdminLoginInfoVO对象
            AdminLoginInfoVO adminLoginInfoVO = new AdminLoginInfoVO();
            adminLoginInfoVO.setId(id);
            adminLoginInfoVO.setUsername(username);
            adminLoginInfoVO.setEnable(enable);
            adminLoginInfoVO.setRoles(Arrays.asList(roles.split(",")));
            adminLoginInfoVO.setPermissions(Arrays.asList(permissions.split(",")));
            log.debug("解析JWT成功, 结果: {}", adminLoginInfoVO);
            return adminLoginInfoVO;
        } catch (ExpiredJwtException e) {
            log.error("JWT已过期", e);
            throw new ServiceException(ServiceCode.ERR_JWT_EXPIRED, "JWT过期");
        } catch (SignatureException e) {
            log.error("JWT解析失败", e);
            throw new ServiceException(ServiceCode.ERR_JWT_SIGNATURE, "令牌无效");
        } catch (Exception e) {
            log.error("JWT解析失败", e);
            throw new ServiceException(ServiceCode.ERR_JWT_MALFORMED, "令牌无效");
        }
    }
}
